home *** CD-ROM | disk | FTP | other *** search
- Subject: v21i094: An Automounter for NFS systems, Part06/13
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: f4c21c41 4b56c24e 5217246d 0db39196
-
- Submitted-by: Jan-Simon Pendry <jsp@doc.ic.ac.uk>
- Posting-number: Volume 21, Issue 94
- Archive-name: amd/part06
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 6 (of 13)."
- # Contents: INSTALL misc_rpc.c nfs_prot_xdr.c nfs_start.c nfs_stubs.c
- # rpc_fwd.c
- # Wrapped by rsalz@papaya.bbn.com on Tue Apr 10 15:12:06 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'INSTALL' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'INSTALL'\"
- else
- echo shar: Extracting \"'INSTALL'\" \(7869 characters\)
- sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
- XInstallation Notes for Amd.
- X
- XNOTE: Please read all of this before starting.
- X It is not very long and may save you time in the long term.
- X
- X1. ``Getting started...''
- X
- XIf you got this release in a shar file then run the shell script Configure in
- Xthe top directory. If you got this release in a tar file then you are all
- Xset (though if you feel left out you can type run Configure anyway).
- X
- X2. ``Find out what version of UN*X you are running...''
- X
- XTo install Amd you need a port for your version of UN*X. In this directory
- Xare several files called os-*.h. One of these should correspond to your
- Xversion of UN*X. Look at the comments at the top of each file to determine
- Xwhich one applies to you. If none of them do, then either no-one has yet
- Xdone a port, or your version of UN*X is so braindead that a port is not
- Xpossible (e.g. System V without reliable signals). Run the program "os-type"
- Xin the current directory to see whether you and Amd are in agreement about
- Xyour operating system type. The current known operating systems (grouped by
- Xarchitecture) are:
- X
- X acis43 ACIS 4.3BSD on an IBM RT/PC
- X bsd44 4.4 BSD on a Tahoe (or Vax)
- X concentrix Concentrix on an Alliant
- X hlh42 4.2 BSD on HLH Orion 1/05
- X hpux HP-UX 6.* on a HP9000/300
- X riscix 4.3 BSD on an Acorn Archimedes
- X sos3, sos4 SunOS 3.x and 4.* on a Sun-3 and Sun-4
- X u2_2 Ultrix 2.2 (or 2.*?) on a VAX
- X u3_0 Ultrix 3.0 (or 3.*?) on a VAX
- X umax43 4.3 BSD on an Encore Multimax
- X utx32 UTX/32 Rel2.1a on a Gould (not yet complete)
- X xinu43 More/BSD (4.3 BSD) on a VAX or HP9000/300
- X
- XIf you do define a new operating system type foo, you may care to create a
- Xfile called Makefile.foo which defines the special Makefile parameters.
- X
- X3. ``Hacking the Makefile...''
- X
- XSome UN*X programs come with a Makefile which has to be manually configured
- Xfor your particular operating system and hardware. However, Amd tries very
- Xhard to determine what type of machine you are using and how best to compile
- Xitself. If this does not work then you will have to find some heuristic
- Xwhich can differentiate your configuration. You may need to edit "arch" and
- X"os-type". If you do make sure your changes can cope if /etc/motd is missing
- Xand please send it to the address below.
- X
- XYou may care to tailor some site specific preferences in "Makefile.com". The
- Xvariables most likely to be changes are at the top. Any changes are best put
- Xin the file Makefile.local (if they are applicable to all operating systems
- Xat your site) or Makefile.local.foo (where foo is the OS type as determined
- Xin part 1).
- X
- XAdditionally, some configuration options may be altered in "Makefile.config".
- XThis means that you should not need to edit any distributed files apart from
- X"Makefile.config". As a minimum, you should check:
- X
- X* You are using the correct C compiler. Amd, as shipped, does not use GCC.
- X Note that using GCC version 1.34 or later (e.g. 1.36) gives structure
- X passing problems with some parts of Sun's RPC library at least on Sun-4's.
- X The current workaround is to use the system CC to compile the part of the
- X automounter that gets hit by this problem. [[This is not the same problem
- X that is fixed by -fpcc-struct-return.]] Amd contains no "register"
- X declarations, so using old PCC based code generators is probably bad news.
- X
- X* The installation directory (ETC) is set up correctly.
- X
- X* If you are running tests then it may be worth switching on the DEBUG flag
- X which will cause a running commentary to be printed to the log file.
- X
- X4. ``Build the executable...''
- X
- XNow you need to compile the automounter. To do this you type:
- X
- X make
- X
- XIf you are porting to a new machine you may want to do:
- X
- X make OS=foo
- X
- Xwhere foo is the name of your version of UN*X as determined in part 1, until
- Xyou have made the changes to os-type and/or arch. When the compilation is
- Xcomplete you will end up with a program called "arch.foo/Amd".
- X
- XTry running:
- X
- X arch.foo/Amd -v
- X
- Xand check the output. It should look something like:
- X
- X amd 5.1.1.6 of 90/01/10 17:30:40 Rel5.1c #0: Wed Jan 10 17:38:34 GMT 1990
- X Built by jsp@elsinore.doc.ic.ac.uk for an ibm032 running acis43 (big-endian)
- X Map support for: root, hesiod, error.
- X
- XMake sure the O/S and architecture types were correctly derived during the
- Xbuild.
- X
- XNOTE: If you are building for Ultrix 2.2 then you *may* need to use the
- Xsystem V make (s5make) or GNU make instead of /bin/make. To do that run:
- X
- X make MAKE=s5make
- Xor
- X make MAKE=gmake
- X
- X5. ``Installation...''
- X
- XIf you are not just testing Amd, then you can install it by typing:
- X
- X make install
- X
- Xto install "arch.foo/Amd" in "/usr/local/etc/Amd" (or as otherwise
- Xmodified in part 2).
- X
- X6. ``Update /etc/rpc''
- X
- XAmq uses Sun RPC to talk to Amd using program number 300019 which has
- Xbeen registered with Sun. Add the following lines to /etc/rpc or your
- XYP or Hesiod master:
- X
- X# Automount control protocol
- Xamd 300019 amq
- X
- X7. ``Hanging your machine...''
- X
- XWARNING: THIS MAY HANG YOUR MACHINE IF YOU GET IT WRONG.
- X
- XRunning Amd with a carelessly thought out mount map can cause your Amd to
- Xenter a deadlock inside the kernel. For example, attempting to automount a
- Xdirectory which is automounted can cause the automounter to issue a mount
- Xrequest which will cause the kernel to send an NFS request back to the same
- Xautomounter, which is currently stuck in a system call and unable to respond
- X- even kill -KILL won't get you out of this one.
- X
- XThere is nothing you can do to fix it without rebooting your machine, so...
- X
- XFind a diskless workstation and play with that first before trying this on
- Xyour main 200 user service machine (unless you hate your users). Something
- Xlike a diskless Sun-4 is best for development testing - you can compile on a
- XSun-4 server and run the binary on the diskless node. They reboot very fast
- Xas well between tests.
- X
- XNow you can try running Amd. Please read the documentation in doc/Amd.tex
- Xfor more details. The configuration file "a_master" provides a sample for
- Xyou to play with. Something like:
- X
- X ./Amd -c 40 -D test,nodaemon /tmp/amnt a_master &
- X
- Xis good for testing. Note that Amd will clean up correctly if you send it a
- XSIGINT or SIGTERM. Other signals are either ignored or will blow it away,
- Xleaving your machine in a potentially dangerous state - usually a reboot is
- Xall that is required to fix it though ;-)
- X
- XRemember that Amd needs to run as root in order to do mounts/unmounts though
- Xit does check this condition somewhere near line one of main(). It will also
- Xneed write permission in the working directory if you have built it with
- XDEBUG defined. Watch out for NFS stepping in and mapping root to nobody.
- X
- X8. ``Report what happened...''
- X
- XIf anything interesting happened, eg it didn't work, please report it to me
- X-- Jan-Simon Pendry <jsp@doc.ic.ac.uk> -- as detailed in the README file.
- X
- XKNOWN PROBLEMS - Contact me for more details
- X
- X* Amd does not work correctly on a DecStation 3100 system running Ultrix 3.1.
- X This is a bug in Ultrix. Quite how the Ultrix mount command works is a
- X total mystery, but in any case the mount system call does not behave as
- X documented.
- X
- X* It is reported that amd deadlocks the kernel on a Sequent Symmetry.
- X Obviously this is a kernel bug.
- X
- X* Amd cannot do hierarchical mounts, ie mount two or more filesystems at
- X once. To do this requires resolving some non-trivial issues. If you think
- X you know what the semantics should be I would like to hear from you.
- X Remember to consider the general case. The tree of mounts can be composed
- X of any combination of filesystem types, and/or possibly come from several
- X NFS servers any of which may be down at the time of the mount.
- X
- X Once the tree is mounted, how does it get unmounted? Again, what happens
- X if a fileserver is down, or goes down after one of the other filesystems is
- X unmounted?
- X
- X$Id: INSTALL,v 5.1.1.2 90/01/11 16:45:44 jsp Exp Locker: jsp $
- END_OF_FILE
- if test 7869 -ne `wc -c <'INSTALL'`; then
- echo shar: \"'INSTALL'\" unpacked with wrong size!
- fi
- # end of 'INSTALL'
- fi
- if test -f 'misc_rpc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'misc_rpc.c'\"
- else
- echo shar: Extracting \"'misc_rpc.c'\" \(8404 characters\)
- sed "s/^X//" >'misc_rpc.c' <<'END_OF_FILE'
- X/*
- X * $Id: misc_rpc.c,v 5.1.1.1 90/01/11 17:08:49 jsp Exp Locker: jsp $
- X *
- X * Copyright (c) 1990 Jan-Simon Pendry
- X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- X * Copyright (c) 1990 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Jan-Simon Pendry at Imperial College, London.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Imperial College of Science, Technology and Medicine, London, UK.
- X * The names of the College and University may not be used to endorse
- X * or promote products derived from this software without specific
- X * prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X *
- X * %W% (Berkeley) %G%
- X */
- X
- X/*
- X * Additions to Sun RPC.
- X */
- X
- X#include "am.h"
- X
- Xvoid rpc_msg_init P((struct rpc_msg *mp, u_long prog, u_long vers, u_long proc));
- Xvoid rpc_msg_init(mp, prog, vers, proc)
- Xstruct rpc_msg *mp;
- Xunsigned long prog, vers, proc;
- X{
- X /*
- X * Initialise the message
- X */
- X bzero((voidp) mp, sizeof(*mp));
- X mp->rm_xid = 0;
- X mp->rm_direction = CALL;
- X mp->rm_call.cb_rpcvers = RPC_MSG_VERSION;
- X mp->rm_call.cb_prog = prog;
- X mp->rm_call.cb_vers = vers;
- X mp->rm_call.cb_proc = proc;
- X}
- X
- X/*
- X * Field reply to call to mountd
- X */
- Xint pickup_rpc_reply P((voidp pkt, int len, voidp where, xdrproc_t where_xdr));
- Xint pickup_rpc_reply(pkt, len, where, where_xdr)
- Xvoidp pkt;
- Xint len;
- Xvoidp where;
- Xxdrproc_t where_xdr;
- X{
- X XDR reply_xdr;
- X int ok;
- X struct rpc_err err;
- X struct rpc_msg reply_msg;
- X int error = 0;
- X
- X /*bzero((voidp) &err, sizeof(err));*/
- X bzero((voidp) &reply_msg, sizeof(reply_msg));
- X
- X reply_msg.acpted_rply.ar_results.where = (caddr_t) where;
- X reply_msg.acpted_rply.ar_results.proc = where_xdr;
- X
- X xdrmem_create(&reply_xdr, pkt, len, XDR_DECODE);
- X
- X ok = xdr_replymsg(&reply_xdr, &reply_msg);
- X if (!ok) {
- X error = EIO;
- X goto drop;
- X }
- X _seterr_reply(&reply_msg, &err);
- X if (err.re_status != RPC_SUCCESS) {
- X error = EIO;
- X goto drop;
- X }
- X
- Xdrop:
- X if (reply_msg.acpted_rply.ar_verf.oa_base) {
- X reply_xdr.x_op = XDR_FREE;
- X (void)xdr_opaque_auth(&reply_xdr,
- X &reply_msg.acpted_rply.ar_verf);
- X }
- X xdr_destroy(&reply_xdr);
- X
- X return error;
- X}
- X
- Xint make_rpc_packet P((char *buf, int buflen, unsigned long proc,
- X struct rpc_msg *mp, voidp arg, xdrproc_t arg_xdr, AUTH *auth));
- Xint make_rpc_packet(buf, buflen, proc, mp, arg, arg_xdr, auth)
- Xchar *buf;
- Xint buflen;
- Xunsigned long proc;
- Xstruct rpc_msg *mp;
- Xvoidp arg;
- Xxdrproc_t arg_xdr;
- XAUTH *auth;
- X{
- X XDR msg_xdr;
- X int len;
- X
- X xdrmem_create(&msg_xdr, buf, buflen, XDR_ENCODE);
- X /*
- X * Basic protocol header
- X */
- X if (!xdr_callhdr(&msg_xdr, mp))
- X return -EIO;
- X /*
- X * Called procedure number
- X */
- X if (!xdr_enum(&msg_xdr, &proc))
- X return -EIO;
- X /*
- X * Authorization
- X */
- X if (!AUTH_MARSHALL(auth, &msg_xdr))
- X return -EIO;
- X /*
- X * Arguments
- X */
- X if (!(*arg_xdr)(&msg_xdr, arg))
- X return -EIO;
- X /*
- X * Determine length
- X */
- X len = xdr_getpos(&msg_xdr);
- X /*
- X * Throw away xdr
- X */
- X xdr_destroy(&msg_xdr);
- X return len;
- X}
- X
- X
- X#ifdef MISC_RPC
- X/*
- X * Early RPC seems to be missing these..
- X * Extracted from the RPC 3.9 sources as indicated
- X */
- X
- X/* @(#)xdr_reference.c 1.1 87/11/04 3.9 RPCSRC */
- X/*
- X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- X * unrestricted use provided that this legend is included on all tape
- X * media and as a part of the software program in whole or part. Users
- X * may copy or modify Sun RPC without charge, but are not authorized
- X * to license or distribute it to anyone else except as part of a product or
- X * program developed by the user.
- X *
- X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- X *
- X * Sun RPC is provided with no support and without any obligation on the
- X * part of Sun Microsystems, Inc. to assist in its use, correction,
- X * modification or enhancement.
- X *
- X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- X * OR ANY PART THEREOF.
- X *
- X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- X * or profits or other special, indirect and consequential damages, even if
- X * Sun has been advised of the possibility of such damages.
- X *
- X * Sun Microsystems, Inc.
- X * 2550 Garcia Avenue
- X * Mountain View, California 94043
- X */
- X
- X
- X/*
- X * xdr_pointer():
- X *
- X * XDR a pointer to a possibly recursive data structure. This
- X * differs with xdr_reference in that it can serialize/deserialiaze
- X * trees correctly.
- X *
- X * What's sent is actually a union:
- X *
- X * union object_pointer switch (boolean b) {
- X * case TRUE: object_data data;
- X * case FALSE: void nothing;
- X * }
- X *
- X * > objpp: Pointer to the pointer to the object.
- X * > obj_size: size of the object.
- X * > xdr_obj: routine to XDR an object.
- X *
- X */
- Xbool_t
- Xxdr_pointer(xdrs,objpp,obj_size,xdr_obj)
- X register XDR *xdrs;
- X char **objpp;
- X u_int obj_size;
- X xdrproc_t xdr_obj;
- X{
- X
- X bool_t more_data;
- X
- X more_data = (*objpp != NULL);
- X if (! xdr_bool(xdrs,&more_data)) {
- X return (FALSE);
- X }
- X if (! more_data) {
- X *objpp = NULL;
- X return (TRUE);
- X }
- X return (xdr_reference(xdrs,objpp,obj_size,xdr_obj));
- X}
- X
- X/* @(#)clnt_perror.c 1.1 87/11/04 3.9 RPCSRC */
- X/*
- X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- X * unrestricted use provided that this legend is included on all tape
- X * media and as a part of the software program in whole or part. Users
- X * may copy or modify Sun RPC without charge, but are not authorized
- X * to license or distribute it to anyone else except as part of a product or
- X * program developed by the user.
- X *
- X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- X *
- X * Sun RPC is provided with no support and without any obligation on the
- X * part of Sun Microsystems, Inc. to assist in its use, correction,
- X * modification or enhancement.
- X *
- X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- X * OR ANY PART THEREOF.
- X *
- X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- X * or profits or other special, indirect and consequential damages, even if
- X * Sun has been advised of the possibility of such damages.
- X *
- X * Sun Microsystems, Inc.
- X * 2550 Garcia Avenue
- X * Mountain View, California 94043
- X */
- X
- Xstruct rpc_errtab {
- X enum clnt_stat status;
- X char *message;
- X};
- X
- Xstatic struct rpc_errtab rpc_errlist[] = {
- X { RPC_SUCCESS,
- X "RPC: Success" },
- X { RPC_CANTENCODEARGS,
- X "RPC: Can't encode arguments" },
- X { RPC_CANTDECODERES,
- X "RPC: Can't decode result" },
- X { RPC_CANTSEND,
- X "RPC: Unable to send" },
- X { RPC_CANTRECV,
- X "RPC: Unable to receive" },
- X { RPC_TIMEDOUT,
- X "RPC: Timed out" },
- X { RPC_VERSMISMATCH,
- X "RPC: Incompatible versions of RPC" },
- X { RPC_AUTHERROR,
- X "RPC: Authentication error" },
- X { RPC_PROGUNAVAIL,
- X "RPC: Program unavailable" },
- X { RPC_PROGVERSMISMATCH,
- X "RPC: Program/version mismatch" },
- X { RPC_PROCUNAVAIL,
- X "RPC: Procedure unavailable" },
- X { RPC_CANTDECODEARGS,
- X "RPC: Server can't decode arguments" },
- X { RPC_SYSTEMERROR,
- X "RPC: Remote system error" },
- X { RPC_UNKNOWNHOST,
- X "RPC: Unknown host" },
- X/* { RPC_UNKNOWNPROTO,
- X "RPC: Unknown protocol" },*/
- X { RPC_PMAPFAILURE,
- X "RPC: Port mapper failure" },
- X { RPC_PROGNOTREGISTERED,
- X "RPC: Program not registered"},
- X { RPC_FAILED,
- X "RPC: Failed (unspecified error)"}
- X};
- X
- X
- X/*
- X * This interface for use by clntrpc
- X */
- Xchar *
- Xclnt_sperrno(stat)
- X enum clnt_stat stat;
- X{
- X int i;
- X
- X for (i = 0; i < sizeof(rpc_errlist)/sizeof(struct rpc_errtab); i++) {
- X if (rpc_errlist[i].status == stat) {
- X return (rpc_errlist[i].message);
- X }
- X }
- X return ("RPC: (unknown error code)");
- X}
- X
- X#endif /* MISC_RPC */
- X
- END_OF_FILE
- if test 8404 -ne `wc -c <'misc_rpc.c'`; then
- echo shar: \"'misc_rpc.c'\" unpacked with wrong size!
- fi
- # end of 'misc_rpc.c'
- fi
- if test -f 'nfs_prot_xdr.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'nfs_prot_xdr.c'\"
- else
- echo shar: Extracting \"'nfs_prot_xdr.c'\" \(9341 characters\)
- sed "s/^X//" >'nfs_prot_xdr.c' <<'END_OF_FILE'
- X/*
- X * $Id: nfs_prot_xdr.c,v 5.1 89/11/17 18:21:28 jsp Exp Locker: jsp $
- X *
- X * Copyright (c) 1989 Jan-Simon Pendry
- X * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- X * Copyright (c) 1989 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Jan-Simon Pendry at Imperial College, London.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Imperial College of Science, Technology and Medicine, London, UK.
- X * The names of the College and University may not be used to endorse
- X * or promote products derived from this software without specific
- X * prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X *
- X * %W% (Berkeley) %G%
- X */
- X
- X#include "am.h"
- X
- X
- X#ifndef xdr_nfsstat
- Xbool_t
- Xxdr_nfsstat(xdrs, objp)
- X XDR *xdrs;
- X nfsstat *objp;
- X{
- X if (!xdr_enum(xdrs, (enum_t *)objp)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X#endif
- X
- X
- X
- X#ifndef xdr_ftype
- Xstatic bool_t
- Xxdr_ftype(xdrs, objp)
- X XDR *xdrs;
- X ftype *objp;
- X{
- X if (!xdr_enum(xdrs, (enum_t *)objp)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X#endif
- X
- X
- X
- Xbool_t
- Xxdr_nfs_fh(xdrs, objp)
- X XDR *xdrs;
- X nfs_fh *objp;
- X{
- X if (!xdr_opaque(xdrs, objp->data, NFS_FHSIZE)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xstatic bool_t
- Xxdr_nfstime(xdrs, objp)
- X XDR *xdrs;
- X nfstime *objp;
- X{
- X if (!xdr_u_int(xdrs, &objp->seconds)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->useconds)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xstatic bool_t
- Xxdr_fattr(xdrs, objp)
- X XDR *xdrs;
- X fattr *objp;
- X{
- X if (!xdr_ftype(xdrs, &objp->type)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->mode)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->nlink)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->uid)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->gid)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->size)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->blocksize)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->rdev)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->blocks)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->fsid)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->fileid)) {
- X return (FALSE);
- X }
- X if (!xdr_nfstime(xdrs, &objp->atime)) {
- X return (FALSE);
- X }
- X if (!xdr_nfstime(xdrs, &objp->mtime)) {
- X return (FALSE);
- X }
- X if (!xdr_nfstime(xdrs, &objp->ctime)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xstatic bool_t
- Xxdr_sattr(xdrs, objp)
- X XDR *xdrs;
- X sattr *objp;
- X{
- X if (!xdr_u_int(xdrs, &objp->mode)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->uid)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->gid)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->size)) {
- X return (FALSE);
- X }
- X if (!xdr_nfstime(xdrs, &objp->atime)) {
- X return (FALSE);
- X }
- X if (!xdr_nfstime(xdrs, &objp->mtime)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xstatic bool_t
- Xxdr_filename(xdrs, objp)
- X XDR *xdrs;
- X filename *objp;
- X{
- X if (!xdr_string(xdrs, objp, NFS_MAXNAMLEN)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_nfspath(xdrs, objp)
- X XDR *xdrs;
- X nfspath *objp;
- X{
- X if (!xdr_string(xdrs, objp, NFS_MAXPATHLEN)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_attrstat(xdrs, objp)
- X XDR *xdrs;
- X attrstat *objp;
- X{
- X if (!xdr_nfsstat(xdrs, &objp->status)) {
- X return (FALSE);
- X }
- X switch (objp->status) {
- X case NFS_OK:
- X if (!xdr_fattr(xdrs, &objp->attrstat_u.attributes)) {
- X return (FALSE);
- X }
- X break;
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_sattrargs(xdrs, objp)
- X XDR *xdrs;
- X sattrargs *objp;
- X{
- X if (!xdr_nfs_fh(xdrs, &objp->file)) {
- X return (FALSE);
- X }
- X if (!xdr_sattr(xdrs, &objp->attributes)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_diropargs(xdrs, objp)
- X XDR *xdrs;
- X diropargs *objp;
- X{
- X if (!xdr_nfs_fh(xdrs, &objp->dir)) {
- X return (FALSE);
- X }
- X if (!xdr_filename(xdrs, &objp->name)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_diropokres(xdrs, objp)
- X XDR *xdrs;
- X diropokres *objp;
- X{
- X if (!xdr_nfs_fh(xdrs, &objp->file)) {
- X return (FALSE);
- X }
- X if (!xdr_fattr(xdrs, &objp->attributes)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_diropres(xdrs, objp)
- X XDR *xdrs;
- X diropres *objp;
- X{
- X if (!xdr_nfsstat(xdrs, &objp->status)) {
- X return (FALSE);
- X }
- X switch (objp->status) {
- X case NFS_OK:
- X if (!xdr_diropokres(xdrs, &objp->diropres_u.diropres)) {
- X return (FALSE);
- X }
- X break;
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_readlinkres(xdrs, objp)
- X XDR *xdrs;
- X readlinkres *objp;
- X{
- X if (!xdr_nfsstat(xdrs, &objp->status)) {
- X return (FALSE);
- X }
- X switch (objp->status) {
- X case NFS_OK:
- X if (!xdr_nfspath(xdrs, &objp->readlinkres_u.data)) {
- X return (FALSE);
- X }
- X break;
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_readargs(xdrs, objp)
- X XDR *xdrs;
- X readargs *objp;
- X{
- X if (!xdr_nfs_fh(xdrs, &objp->file)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->offset)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->count)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->totalcount)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_readokres(xdrs, objp)
- X XDR *xdrs;
- X readokres *objp;
- X{
- X if (!xdr_fattr(xdrs, &objp->attributes)) {
- X return (FALSE);
- X }
- X if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_readres(xdrs, objp)
- X XDR *xdrs;
- X readres *objp;
- X{
- X if (!xdr_nfsstat(xdrs, &objp->status)) {
- X return (FALSE);
- X }
- X switch (objp->status) {
- X case NFS_OK:
- X if (!xdr_readokres(xdrs, &objp->readres_u.reply)) {
- X return (FALSE);
- X }
- X break;
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_writeargs(xdrs, objp)
- X XDR *xdrs;
- X writeargs *objp;
- X{
- X if (!xdr_nfs_fh(xdrs, &objp->file)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->beginoffset)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->offset)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->totalcount)) {
- X return (FALSE);
- X }
- X if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_createargs(xdrs, objp)
- X XDR *xdrs;
- X createargs *objp;
- X{
- X if (!xdr_diropargs(xdrs, &objp->where)) {
- X return (FALSE);
- X }
- X if (!xdr_sattr(xdrs, &objp->attributes)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_renameargs(xdrs, objp)
- X XDR *xdrs;
- X renameargs *objp;
- X{
- X if (!xdr_diropargs(xdrs, &objp->from)) {
- X return (FALSE);
- X }
- X if (!xdr_diropargs(xdrs, &objp->to)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_linkargs(xdrs, objp)
- X XDR *xdrs;
- X linkargs *objp;
- X{
- X if (!xdr_nfs_fh(xdrs, &objp->from)) {
- X return (FALSE);
- X }
- X if (!xdr_diropargs(xdrs, &objp->to)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_symlinkargs(xdrs, objp)
- X XDR *xdrs;
- X symlinkargs *objp;
- X{
- X if (!xdr_diropargs(xdrs, &objp->from)) {
- X return (FALSE);
- X }
- X if (!xdr_nfspath(xdrs, &objp->to)) {
- X return (FALSE);
- X }
- X if (!xdr_sattr(xdrs, &objp->attributes)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xstatic bool_t
- Xxdr_nfscookie(xdrs, objp)
- X XDR *xdrs;
- X nfscookie objp;
- X{
- X if (!xdr_opaque(xdrs, objp, NFS_COOKIESIZE)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_readdirargs(xdrs, objp)
- X XDR *xdrs;
- X readdirargs *objp;
- X{
- X if (!xdr_nfs_fh(xdrs, &objp->dir)) {
- X return (FALSE);
- X }
- X if (!xdr_nfscookie(xdrs, objp->cookie)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->count)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xstatic bool_t
- Xxdr_entry(xdrs, objp)
- X XDR *xdrs;
- X entry *objp;
- X{
- X if (!xdr_u_int(xdrs, &objp->fileid)) {
- X return (FALSE);
- X }
- X if (!xdr_filename(xdrs, &objp->name)) {
- X return (FALSE);
- X }
- X if (!xdr_nfscookie(xdrs, objp->cookie)) {
- X return (FALSE);
- X }
- X if (!xdr_pointer(xdrs, (char **)&objp->nextentry, sizeof(entry), xdr_entry)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xstatic bool_t
- Xxdr_dirlist(xdrs, objp)
- X XDR *xdrs;
- X dirlist *objp;
- X{
- X if (!xdr_pointer(xdrs, (char **)&objp->entries, sizeof(entry), xdr_entry)) {
- X return (FALSE);
- X }
- X if (!xdr_bool(xdrs, &objp->eof)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_readdirres(xdrs, objp)
- X XDR *xdrs;
- X readdirres *objp;
- X{
- X if (!xdr_nfsstat(xdrs, &objp->status)) {
- X return (FALSE);
- X }
- X switch (objp->status) {
- X case NFS_OK:
- X if (!xdr_dirlist(xdrs, &objp->readdirres_u.reply)) {
- X return (FALSE);
- X }
- X break;
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_statfsokres(xdrs, objp)
- X XDR *xdrs;
- X statfsokres *objp;
- X{
- X if (!xdr_u_int(xdrs, &objp->tsize)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->bsize)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->blocks)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->bfree)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->bavail)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- X
- X
- X
- Xbool_t
- Xxdr_statfsres(xdrs, objp)
- X XDR *xdrs;
- X statfsres *objp;
- X{
- X if (!xdr_nfsstat(xdrs, &objp->status)) {
- X return (FALSE);
- X }
- X switch (objp->status) {
- X case NFS_OK:
- X if (!xdr_statfsokres(xdrs, &objp->statfsres_u.reply)) {
- X return (FALSE);
- X }
- X break;
- X }
- X return (TRUE);
- X}
- END_OF_FILE
- if test 9341 -ne `wc -c <'nfs_prot_xdr.c'`; then
- echo shar: \"'nfs_prot_xdr.c'\" unpacked with wrong size!
- fi
- # end of 'nfs_prot_xdr.c'
- fi
- if test -f 'nfs_start.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'nfs_start.c'\"
- else
- echo shar: Extracting \"'nfs_start.c'\" \(7449 characters\)
- sed "s/^X//" >'nfs_start.c' <<'END_OF_FILE'
- X/*
- X * $Id: nfs_start.c,v 5.1.1.2 90/01/11 17:13:06 jsp Exp Locker: jsp $
- X *
- X * Copyright (c) 1990 Jan-Simon Pendry
- X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- X * Copyright (c) 1990 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Jan-Simon Pendry at Imperial College, London.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Imperial College of Science, Technology and Medicine, London, UK.
- X * The names of the College and University may not be used to endorse
- X * or promote products derived from this software without specific
- X * prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X *
- X * %W% (Berkeley) %G%
- X */
- X
- X#include "am.h"
- X#include "amq.h"
- X#include <sys/signal.h>
- X#include <setjmp.h>
- Xextern jmp_buf select_intr;
- Xextern int select_intr_valid;
- X
- X#ifdef HAS_TFS
- X/*
- X * Use replacement for RPC/UDP transport
- X * so that we do NFS gatewaying.
- X */
- X#define svcudp_create svcudp2_create
- Xextern SVCXPRT *svcudp2_create P((int));
- X#endif
- X
- Xextern void nfs_program_2();
- Xextern void amq_program_1();
- X
- Xunsigned short nfs_port;
- XSVCXPRT *nfsxprt;
- X
- Xextern int fwd_sock;
- X
- X#ifndef NFDS
- Xstatic int nfds = -1;
- X#ifdef FD_SET
- X#define NFDS (nfds < 0 ? nfds = getdtablesize() : nfds)
- X#else
- X#define NFDS (sizeof(int) * 8)
- X#endif
- X#endif
- X
- X#define MASKED_SIGS (sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGCHLD)|sigmask(SIGHUP))
- X
- X#ifdef DEBUG
- X/*
- X * Check that we are not burning resources
- X */
- Xstatic void checkup(P_void)
- X{
- X
- Xstatic int max_fd = 0;
- Xstatic char *max_mem = 0;
- X
- X int next_fd = dup(0);
- X extern caddr_t sbrk P((int));
- X caddr_t next_mem = sbrk(0);
- X close(next_fd);
- X
- X /*if (max_fd < 0) {
- X max_fd = next_fd;
- X } else*/ if (max_fd < next_fd) {
- X dlog("%d new fds allocated; total is %d",
- X next_fd - max_fd, next_fd);
- X max_fd = next_fd;
- X }
- X
- X /*if (max_mem == 0) {
- X max_mem = next_mem;
- X } else*/ if (max_mem < next_mem) {
- X dlog("%#x bytes of memory allocated; total is %#x (%d pages)",
- X next_mem - max_mem,
- X next_mem,
- X ((int)next_mem+getpagesize()-1)/getpagesize());
- X max_mem = next_mem;
- X }
- X}
- X#endif
- X
- Xstatic int do_select(smask, fds, fdp, tvp)
- Xint smask;
- Xint fds;
- Xint *fdp;
- Xstruct timeval *tvp;
- X{
- X int sig;
- X int nsel;
- X if (sig = setjmp(select_intr)) {
- X select_intr_valid = 0;
- X /* Got a signal */
- X switch (sig) {
- X case SIGINT:
- X case SIGTERM:
- X amd_state = Finishing;
- X reschedule_timeout_mp();
- X break;
- X }
- X nsel = -1;
- X errno = EINTR;
- X } else {
- X select_intr_valid = 1;
- X /*
- X * Invalidate the current clock value
- X */
- X clock_valid = 0;
- X /*
- X * Allow interrupts. If a signal
- X * occurs, then it will cause a longjmp
- X * up above.
- X */
- X (void) sigsetmask(smask);
- X /*
- X * Wait for input
- X */
- X nsel = select(fds, fdp, (int *) 0, (int *) 0,
- X tvp->tv_sec ? tvp : (struct timeval *) 0);
- X
- X }
- X
- X (void) sigblock(MASKED_SIGS);
- X
- X /*
- X * Perhaps reload the cache?
- X */
- X if (do_mapc_reload < clocktime()) {
- X mapc_reload();
- X do_mapc_reload = clocktime() + ONE_HOUR;
- X }
- X return nsel;
- X}
- X
- Xstatic serv_state run_rpc(P_void)
- X{
- X int dtbsz = NFDS;
- X int smask = sigblock(MASKED_SIGS);
- X
- X next_softclock = clocktime();
- X
- X amd_state = Run;
- X
- X /*
- X * Keep on trucking while we are in Run mode. This state
- X * is switched to Quit after all the file systems have
- X * been unmounted.
- X */
- X while ((int)amd_state <= (int)Finishing) {
- X struct timeval tvv;
- X int nsel;
- X time_t now;
- X#ifdef RPC_4
- X fd_set readfds;
- X readfds = svc_fdset;
- X FD_SET(fwd_sock, &readfds);
- X#else
- X#ifdef FD_SET
- X fd_set readfds;
- X FD_ZERO(&readfds);
- X readfds.fds_bits[0] = svc_fds;
- X FD_SET(fwd_sock, &readfds);
- X#else
- X int readfds = svc_fds | (1 << fwd_sock);
- X#endif /* FD_SET */
- X#endif /* RPC_4 */
- X
- X#ifdef DEBUG
- X checkup();
- X#endif
- X
- X /*
- X * If the full timeout code is not called,
- X * then recompute the time delta manually.
- X */
- X now = clocktime();
- X
- X if (next_softclock <= now) {
- X if (amd_state == Finishing)
- X umount_exported();
- X tvv.tv_sec = softclock();
- X } else {
- X tvv.tv_sec = next_softclock - now;
- X }
- X tvv.tv_usec = 0;
- X
- X if (amd_state == Finishing && last_used_map < 0) {
- X flush_mntfs();
- X amd_state = Quit;
- X break;
- X }
- X
- X#ifdef DEBUG
- X if (tvv.tv_sec)
- X dlog("Select waits for %ds", tvv.tv_sec);
- X else
- X dlog("Select waits for Godot");
- X#endif
- X
- X nsel = do_select(smask, dtbsz, &readfds, &tvv);
- X
- X
- X switch (nsel) {
- X case -1:
- X if (errno == EINTR) {
- X#ifdef DEBUG
- X dlog("select interrupted");
- X#endif
- X continue;
- X }
- X perror("select");
- X break;
- X
- X case 0:
- X#ifdef DEBUG
- X /*dlog("select returned 0");*/
- X#endif
- X break;
- X
- X default:
- X#ifdef FD_SET
- X if (FD_ISSET(fwd_sock, &readfds)) {
- X FD_CLR(fwd_sock, &readfds);
- X fwd_reply();
- X --nsel;
- X }
- X#else
- X if (readfds & (1 << fwd_sock)) {
- X readfds &= ~(1 << fwd_sock);
- X fwd_reply();
- X --nsel;
- X }
- X#endif
- X
- X if (nsel) {
- X /*
- X * Anything left must be a normal
- X * RPC request.
- X */
- X#ifdef RPC_4
- X svc_getreqset(&readfds);
- X#else
- X#ifdef FD_SET
- X svc_getreq(readfds.fds_bits[0]);
- X#else
- X svc_getreq(readfds);
- X#endif
- X#endif
- X }
- X break;
- X }
- X }
- X
- X (void) sigsetmask(smask);
- X
- X if (amd_state == Quit)
- X amd_state = Done;
- X
- X return amd_state;
- X}
- X
- Xstatic int bindnfs_port(so)
- Xint so;
- X{
- X unsigned short port;
- X int error = bind_resv_port(so, &port);
- X if (error == 0)
- X nfs_port = port;
- X return error;
- X}
- X
- Xvoid unregister_amq(P_void)
- X{
- X#ifdef DEBUG
- X Debug(D_AMQ)
- X#endif
- X (void) pmap_unset(AMQ_PROGRAM, AMQ_VERSION);
- X}
- X
- Xint mount_automounter(ppid)
- Xint ppid;
- X{
- X int so = socket(AF_INET, SOCK_DGRAM, 0);
- X SVCXPRT *amqp;
- X int nmount;
- X
- X unregister_amq();
- X
- X if (so < 0 || bindnfs_port(so) < 0) {
- X perror("Can't create privileged nfs port");
- X return 1;
- X }
- X
- X if ((nfsxprt = svcudp_create(so)) == NULL ||
- X (amqp = svcudp_create(so)) == NULL) {
- X plog(XLOG_FATAL, "cannot create rpc/udp service");
- X return 2;
- X }
- X
- X if (!svc_register(nfsxprt, NFS_PROGRAM, NFS_VERSION, nfs_program_2, 0)) {
- X plog(XLOG_FATAL, "unable to register (NFS_PROGRAM, NFS_VERSION, 0)");
- X return 3;
- X }
- X
- X#ifdef DEBUG
- X Debug(D_AMQ)
- X#endif
- X if (!svc_register(amqp, AMQ_PROGRAM, AMQ_VERSION, amq_program_1, IPPROTO_UDP)) {
- X plog(XLOG_FATAL, "unable to register (AMQ_PROGRAM, AMQ_VERSION, udp)");
- X return 3;
- X }
- X
- X /*
- X * Start RPC forwarding
- X */
- X if (fwd_init() != 0)
- X return 3;
- X
- X /*
- X * Construct the root automount node
- X */
- X make_root_node();
- X
- X /*
- X * Pick up the pieces from a previous run
- X * This is likely to (indirectly) need the rpc_fwd package
- X * so it *must* come after the call to fwd_init().
- X */
- X if (restart_existing_mounts)
- X restart();
- X
- X /*
- X * Mount the top-level auto-mountpoints
- X */
- X nmount = mount_exported();
- X
- X /*
- X * Now safe to tell parent that we are up and running
- X */
- X if (ppid)
- X kill(ppid, SIGQUIT);
- X
- X if (nmount == 0) {
- X plog(XLOG_FATAL, "No work to do - quitting");
- X amd_state = Done;
- X return 0;
- X }
- X
- X /*
- X * Start timeout_mp rolling
- X */
- X reschedule_timeout_mp();
- X
- X /*
- X * Start the server
- X */
- X if (run_rpc() != Done) {
- X plog(XLOG_FATAL, "run_rpc failed");
- X amd_state = Done;
- X }
- X
- X return 0;
- X}
- END_OF_FILE
- if test 7449 -ne `wc -c <'nfs_start.c'`; then
- echo shar: \"'nfs_start.c'\" unpacked with wrong size!
- fi
- # end of 'nfs_start.c'
- fi
- if test -f 'nfs_stubs.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'nfs_stubs.c'\"
- else
- echo shar: Extracting \"'nfs_stubs.c'\" \(9501 characters\)
- sed "s/^X//" >'nfs_stubs.c' <<'END_OF_FILE'
- X/*
- X * $Id: nfs_stubs.c,v 5.1.1.2 90/01/11 17:14:34 jsp Exp Locker: jsp $
- X *
- X * Copyright (c) 1990 Jan-Simon Pendry
- X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- X * Copyright (c) 1990 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Jan-Simon Pendry at Imperial College, London.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Imperial College of Science, Technology and Medicine, London, UK.
- X * The names of the College and University may not be used to endorse
- X * or promote products derived from this software without specific
- X * prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X *
- X * %W% (Berkeley) %G%
- X */
- X
- X#include "am.h"
- X
- X/*
- X * Convert from UN*X to NFS error code
- X */
- X#ifdef NFS_ERROR_MAPPING
- XNFS_ERROR_MAPPING
- X#define nfs_error(e) \
- X ((nfsstat)((e) > NFS_LOMAP && (e) < NFS_HIMAP ? \
- X nfs_errormap[(e) - NFS_LOMAP] : (e)))
- X#else
- X#define nfs_error(e) ((nfsstat)(e))
- X#endif
- X
- Xstatic char *do_readlink(mp, error_return)
- Xam_node *mp;
- Xint *error_return;
- X{
- X /*
- X * If there is a readlink method, then use
- X * that, otherwise if a link exists use
- X * that, otherwise use the mount point.
- X */
- X if (mp->am_mnt->mf_ops->readlink) {
- X int retry = 0;
- X char *ln = (*mp->am_mnt->mf_ops->readlink)(mp, &retry);
- X if (ln == 0)
- X *error_return = retry;
- X /*reschedule_timeout_mp();*/
- X return ln;
- X } else if (mp->am_link) {
- X return mp->am_link;
- X } else {
- X return mp->am_mnt->mf_mount;
- X }
- X}
- X
- X/*ARGSUSED*/
- Xvoidp
- Xnfsproc_null_2(argp, rqstp)
- Xvoidp argp;
- Xstruct svc_req *rqstp;
- X{
- X static char res;
- X
- X return (voidp) &res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xstruct attrstat *
- Xnfsproc_getattr_2(argp, rqstp)
- Xstruct nfs_fh *argp;
- Xstruct svc_req *rqstp;
- X{
- X static struct attrstat res;
- X am_node *mp;
- X int retry;
- X
- X#ifdef DEBUG
- X Debug(D_TRACE)
- X plog(XLOG_DEBUG, "gettattr:");
- X#endif
- X
- X mp = fh_to_mp2(argp, &retry);
- X if (mp == 0) {
- Xgetattr_retry:
- X if (retry < 0)
- X return 0;
- X res.status = nfs_error(retry);
- X } else {
- X if (mp->am_mnt->mf_fattr.type == NFLNK) {
- X /*
- X * Make sure we can read the link
- X */
- X char *ln = do_readlink(mp, &retry);
- X if (ln == 0)
- X goto getattr_retry;
- X mp->am_mnt->mf_fattr.size = strlen(ln);
- X }
- X#ifdef DEBUG
- X Debug(D_TRACE)
- X plog(XLOG_DEBUG, "\tstat(%s), size = %d", mp->am_path, mp->am_mnt->mf_fattr.size);
- X#endif
- X mp->am_stats.s_getattr++;
- X return &mp->am_mnt->mf_attr;
- X }
- X
- X return &res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xstruct attrstat *
- Xnfsproc_setattr_2(argp, rqstp)
- Xstruct sattrargs *argp;
- Xstruct svc_req *rqstp;
- X{
- X static struct attrstat res;
- X
- X if (!fh_to_mp(&argp->file))
- X res.status = nfs_error(ESTALE);
- X else
- X res.status = nfs_error(EROFS);
- X
- X return &res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xvoidp
- Xnfsproc_root_2(argp, rqstp)
- Xvoidp argp;
- Xstruct svc_req *rqstp;
- X{
- X static char res;
- X
- X return (voidp)&res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xstruct diropres *
- Xnfsproc_lookup_2(argp, rqstp)
- Xstruct diropargs *argp;
- Xstruct svc_req *rqstp;
- X{
- X static struct diropres res;
- X am_node *mp;
- X int retry;
- X
- X#ifdef DEBUG
- X Debug(D_TRACE)
- X plog(XLOG_DEBUG, "lookup:");
- X#endif
- X
- X mp = fh_to_mp2(&argp->dir, &retry);
- X if (mp == 0) {
- X if (retry < 0)
- X return 0;
- X res.status = nfs_error(retry);
- X } else {
- X int error;
- X am_node *ap;
- X#ifdef DEBUG
- X Debug(D_TRACE)
- X plog(XLOG_DEBUG, "\tlookuppn(%s, %s)", mp->am_path, argp->name);
- X#endif
- X ap = (*mp->am_mnt->mf_ops->lookuppn)(mp, argp->name, &error, VLOOK_CREATE);
- X if (ap == 0) {
- X if (error < 0) {
- X#ifdef DEBUG
- X dlog("Not sending RPC reply");
- X#endif
- X amd_stats.d_drops++;
- X return 0;
- X }
- X res.status = nfs_error(error);
- X } else {
- X#ifdef DEBUG
- X if (ap->am_mnt->mf_fattr.size < 0)
- X dlog("\tERROR: size = %d!", ap->am_mnt->mf_fattr.size);
- X#endif
- X mp_to_fh(ap, &res.diropres_u.diropres.file);
- X res.diropres_u.diropres.attributes = ap->am_mnt->mf_fattr;
- X res.status = nfs_error(0);
- X }
- X mp->am_stats.s_lookup++;
- X /*reschedule_timeout_mp();*/
- X }
- X
- X return &res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xstruct readlinkres *
- Xnfsproc_readlink_2(argp, rqstp)
- Xstruct nfs_fh *argp;
- Xstruct svc_req *rqstp;
- X{
- X static struct readlinkres res;
- X am_node *mp;
- X int retry;
- X
- X#ifdef DEBUG
- X Debug(D_TRACE)
- X plog(XLOG_DEBUG, "readlink:");
- X#endif
- X
- X mp = fh_to_mp2(argp, &retry);
- X if (mp == 0) {
- X if (retry < 0)
- X return 0;
- X res.status = nfs_error(retry);
- X } else {
- X char *ln = do_readlink(mp, &retry);
- X if (ln == 0) {
- X if (retry < 0)
- X return 0;
- X res.status = nfs_error(retry);
- X } else {
- X res.status = NFS_OK;
- X }
- X#ifdef DEBUG
- X Debug(D_TRACE)
- X if (ln)
- X plog(XLOG_DEBUG, "\treadlink(%s) = %s", mp->am_path, ln);
- X#endif
- X res.readlinkres_u.data = ln;
- X mp->am_stats.s_readlink++;
- X }
- X
- X return &res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xstruct readres *
- Xnfsproc_read_2(argp, rqstp)
- Xstruct readargs *argp;
- Xstruct svc_req *rqstp;
- X{
- X static struct readres res;
- X
- X bzero((char *)&res, sizeof(res));
- X
- X res.status = nfs_error(EACCES);
- X
- X return &res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xvoidp
- Xnfsproc_writecache_2(argp, rqstp)
- Xvoidp argp;
- Xstruct svc_req *rqstp;
- X{
- X static char res;
- X
- X return (voidp) &res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xstruct attrstat *
- Xnfsproc_write_2(argp, rqstp)
- Xwriteargs *argp;
- Xstruct svc_req *rqstp;
- X{
- X static struct attrstat res;
- X
- X if (!fh_to_mp(&argp->file))
- X res.status = nfs_error(ESTALE);
- X else
- X res.status = nfs_error(EROFS);
- X
- X return &res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xstruct diropres *
- Xnfsproc_create_2(argp, rqstp)
- Xcreateargs *argp;
- Xstruct svc_req *rqstp;
- X{
- X static struct diropres res;
- X
- X if (!fh_to_mp(&argp->where.dir))
- X res.status = nfs_error(ESTALE);
- X else
- X res.status = nfs_error(EROFS);
- X
- X return &res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xstatic nfsstat *
- Xunlink_or_rmdir(argp, rqstp, unlinkp)
- Xstruct diropargs *argp;
- Xstruct svc_req *rqstp;
- X{
- X static nfsstat res;
- X int retry;
- X mntfs *mf;
- X am_node *mp = fh_to_mp3(&argp->dir, &retry, VLOOK_DELETE);
- X if (mp == 0) {
- X if (retry < 0)
- X return 0;
- X res = nfs_error(retry);
- X goto out;
- X }
- X mf = mp->am_mnt;
- X if (mf->mf_fattr.type != NFDIR) {
- X res = nfs_error(ENOTDIR);
- X goto out;
- X }
- X#ifdef DEBUG
- X Debug(D_TRACE)
- X plog(XLOG_DEBUG, "\tremove(%s, %s)", mp->am_path, argp->name);
- X#endif
- X mp = (*mp->am_mnt->mf_ops->lookuppn)(mp, argp->name, &retry, VLOOK_DELETE);
- X if (mp == 0) {
- X /*
- X * Ignore retries...
- X */
- X if (retry < 0)
- X retry = 0;
- X /*
- X * Usual NFS workaround...
- X */
- X else if (retry == ENOENT)
- X retry = 0;
- X res = nfs_error(retry);
- X } else {
- X forcibly_timeout_mp(mp);
- X res = NFS_OK;
- X }
- X
- Xout:
- X return &res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xnfsstat *
- Xnfsproc_remove_2(argp, rqstp)
- Xstruct diropargs *argp;
- Xstruct svc_req *rqstp;
- X{
- X return unlink_or_rmdir(argp, rqstp, 1);
- X}
- X
- X/*ARGSUSED*/
- Xnfsstat *
- Xnfsproc_rename_2(argp, rqstp)
- Xrenameargs *argp;
- Xstruct svc_req *rqstp;
- X{
- X static nfsstat res;
- X if (!fh_to_mp(&argp->from.dir) || !fh_to_mp(&argp->to.dir))
- X res = nfs_error(ESTALE);
- X else
- X res = nfs_error(EROFS);
- X return &res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xnfsstat *
- Xnfsproc_link_2(argp, rqstp)
- Xlinkargs *argp;
- Xstruct svc_req *rqstp;
- X{
- X static nfsstat res;
- X if (!fh_to_mp(&argp->from) || !fh_to_mp(&argp->to.dir))
- X res = nfs_error(ESTALE);
- X else
- X res = nfs_error(EROFS);
- X
- X return &res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xnfsstat *
- Xnfsproc_symlink_2(argp, rqstp)
- Xsymlinkargs *argp;
- Xstruct svc_req *rqstp;
- X{
- X static nfsstat res;
- X if (!fh_to_mp(&argp->from.dir))
- X res = nfs_error(ESTALE);
- X else
- X res = nfs_error(EROFS);
- X
- X return &res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xstruct diropres *
- Xnfsproc_mkdir_2(argp, rqstp)
- Xcreateargs *argp;
- Xstruct svc_req *rqstp;
- X{
- X static struct diropres res;
- X if (!fh_to_mp(&argp->where.dir))
- X res.status = nfs_error(ESTALE);
- X else
- X res.status = nfs_error(EROFS);
- X
- X return &res;
- X}
- X
- X
- X/*ARGSUSED*/
- Xnfsstat *
- Xnfsproc_rmdir_2(argp, rqstp)
- Xstruct diropargs *argp;
- Xstruct svc_req *rqstp;
- X{
- X return unlink_or_rmdir(argp, rqstp, 0);
- X}
- X
- X
- X/*ARGSUSED*/
- Xstruct readdirres *
- Xnfsproc_readdir_2(argp, rqstp)
- Xreaddirargs *argp;
- Xstruct svc_req *rqstp;
- X{
- X static readdirres res;
- X static entry e_res[2];
- X am_node *mp;
- X int retry;
- X
- X#ifdef DEBUG
- X Debug(D_TRACE)
- X plog(XLOG_DEBUG, "readdir:");
- X#endif
- X
- X mp = fh_to_mp2(&argp->dir, &retry);
- X if (mp == 0) {
- X if (retry < 0)
- X return 0;
- X res.status = nfs_error(retry);
- X } else {
- X#ifdef DEBUG
- X Debug(D_TRACE)
- X plog(XLOG_DEBUG, "\treaddir(%s)", mp->am_path);
- X#endif
- X res.status = nfs_error((*mp->am_mnt->mf_ops->readdir)(mp, argp->cookie,
- X &res.readdirres_u.reply, e_res));
- X mp->am_stats.s_readdir++;
- X }
- X
- X /* XXX - need to take argp->count into account */
- X
- X return &res;
- X}
- X
- X/*ARGSUSED*/
- Xstruct statfsres *
- Xnfsproc_statfs_2(argp, rqstp)
- Xstruct nfs_fh *argp;
- Xstruct svc_req *rqstp;
- X{
- X static statfsres res;
- X am_node *mp;
- X int retry;
- X
- X#ifdef DEBUG
- X Debug(D_TRACE)
- X plog(XLOG_DEBUG, "statfs:");
- X#endif
- X
- X mp = fh_to_mp2(argp, &retry);
- X if (mp == 0) {
- X if (retry < 0)
- X return 0;
- X res.status = nfs_error(retry);
- X } else {
- X statfsokres *fp;
- X#ifdef DEBUG
- X Debug(D_TRACE)
- X plog(XLOG_DEBUG, "\tstat_fs(%s)", mp->am_path);
- X#endif
- X /*
- X * just return faked up file system information
- X */
- X
- X fp = &res.statfsres_u.reply;
- X
- X fp->tsize = 1024;
- X fp->bsize = 4192;
- X fp->blocks = 0;
- X fp->bfree = 0;
- X fp->bavail = 0;
- X
- X res.status = NFS_OK;
- X mp->am_stats.s_statfs++;
- X }
- X
- X return &res;
- X}
- END_OF_FILE
- if test 9501 -ne `wc -c <'nfs_stubs.c'`; then
- echo shar: \"'nfs_stubs.c'\" unpacked with wrong size!
- fi
- # end of 'nfs_stubs.c'
- fi
- if test -f 'rpc_fwd.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rpc_fwd.c'\"
- else
- echo shar: Extracting \"'rpc_fwd.c'\" \(8861 characters\)
- sed "s/^X//" >'rpc_fwd.c' <<'END_OF_FILE'
- X/*
- X * $Id: rpc_fwd.c,v 5.1 89/11/17 18:22:04 jsp Exp Locker: jsp $
- X *
- X * Copyright (c) 1989 Jan-Simon Pendry
- X * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
- X * Copyright (c) 1989 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software contributed to Berkeley by
- X * Jan-Simon Pendry at Imperial College, London.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Imperial College of Science, Technology and Medicine, London, UK.
- X * The names of the College and University may not be used to endorse
- X * or promote products derived from this software without specific
- X * prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X *
- X * %W% (Berkeley) %G%
- X */
- X
- X/*
- X * RPC packet forwarding
- X */
- X
- X#include "am.h"
- X#include <sys/ioctl.h>
- X#ifndef F_SETFL
- X#include <fcntl.h>
- X#endif
- X#ifndef FNDELAY
- X#include <sys/file.h>
- X#endif
- X
- X/*
- X * Note that the ID field in the external packet is only
- X * ever treated as a 32 bit opaque data object, so there
- X * is no need to convert to and from network byte ordering.
- X */
- X
- X/*
- X * Each pending reply has an rpc_forward structure
- X * associated with it. These have a 15 second lifespan.
- X * If a new structure is required, then an expired
- X * one will be re-allocated if available, otherwise a fresh
- X * one is allocated. Whenever a reply is received the
- X * structure is discarded.
- X */
- Xtypedef struct rpc_forward rpc_forward;
- Xstruct rpc_forward {
- X qelem rf_q; /* Linked list */
- X time_t rf_ttl; /* Time to live */
- X u_int rf_xid; /* Packet id */
- X u_int rf_oldid; /* Original packet id */
- X fwd_fun rf_fwd; /* Forwarding function */
- X voidp rf_ptr;
- X struct sockaddr_in rf_sin;
- X};
- X
- X/*
- X * Head of list of pending replies
- X */
- Xextern qelem rpc_head;
- Xqelem rpc_head = { &rpc_head, &rpc_head };
- X
- Xstatic u_int xid;
- X#define XID_ALLOC() (xid++)
- X
- X#define MAX_PACKET_SIZE 8192 /* Maximum UDP packet size */
- X
- Xint fwd_sock;
- X
- X/*
- X * Allocate a rely structure
- X */
- Xstatic rpc_forward *fwd_alloc()
- X{
- X time_t now = clocktime();
- X rpc_forward *p = 0, *p2;
- X
- X#ifdef DEBUG
- X /*dlog("fwd_alloca: rpc_head = %#x", rpc_head.q_forw);*/
- X#endif
- X /*
- X * First search for an existing expired one.
- X */
- X ITER(p2, rpc_forward, &rpc_head) {
- X if (p2->rf_ttl <= now) {
- X p = p2;
- X break;
- X }
- X }
- X
- X /*
- X * If one couldn't be found then allocate
- X * a new structure and link it at the
- X * head of the list.
- X */
- X if (p) {
- X /*
- X * Call forwarding function to say that
- X * this message was junked.
- X */
- X#ifdef DEBUG
- X dlog("Re-using packet forwarding slot - id %#x", p->rf_xid);
- X#endif
- X if (p->rf_fwd)
- X (*p->rf_fwd)(0, 0, 0, &p->rf_sin, p->rf_ptr, FALSE);
- X rem_que(&p->rf_q);
- X } else {
- X p = ALLOC(rpc_forward);
- X }
- X ins_que(&p->rf_q, &rpc_head);
- X
- X /*
- X * Set the time to live field
- X * Timeout in 43 seconds
- X */
- X p->rf_ttl = now + 43;
- X
- X#ifdef DEBUG
- X /*dlog("fwd_alloca: rpc_head = %#x", rpc_head.q_forw);*/
- X#endif
- X return p;
- X}
- X
- X/*
- X * Free an allocated reply structure.
- X * First unlink it from the list, then
- X * discard it.
- X */
- Xstatic void fwd_free(p)
- Xrpc_forward *p;
- X{
- X#ifdef DEBUG
- X /*dlog("fwd_free: rpc_head = %#x", rpc_head.q_forw);*/
- X#endif
- X rem_que(&p->rf_q);
- X#ifdef DEBUG
- X /*dlog("fwd_free: rpc_head = %#x", rpc_head.q_forw);*/
- X#endif
- X free(p);
- X}
- X
- X/*
- X * Initialise the RPC forwarder
- X */
- Xint fwd_init()
- X{
- X int on = 1;
- X
- X /*
- X * Create ping socket
- X */
- X fwd_sock = socket(AF_INET, SOCK_DGRAM, 0);
- X if (fwd_sock < 0) {
- X plog(XLOG_ERROR, "Unable to create RPC forwarding socket: %m");
- X return errno;
- X }
- X
- X /*
- X * Some things we talk to require a priv port - so make one here
- X */
- X if (bind_resv_port(fwd_sock, (unsigned short *) 0) < 0)
- X plog(XLOG_ERROR, "can't bind privileged port");
- X
- X if (fcntl(fwd_sock, F_SETFL, FNDELAY) < 0 &&
- X ioctl(fwd_sock, FIONBIO, &on) < 0) {
- X plog(XLOG_ERROR, "Can't set non-block on forwarding socket: %m");
- X return errno;
- X }
- X
- X return 0;
- X}
- X
- X/*
- X * Locate a packet in the forwarding list
- X */
- Xstatic rpc_forward *fwd_locate(id)
- Xu_int id;
- X{
- X rpc_forward *p;
- X
- X ITER(p, rpc_forward, &rpc_head) {
- X if (p->rf_xid == id)
- X return p;
- X }
- X
- X return 0;
- X}
- X
- X/*
- X * This is called to forward a packet to another
- X * RPC server. The message id is changed and noted
- X * so that when a reply appears we can tie it up
- X * correctly. Just matching the reply's source address
- X * would not work because it might come from a
- X * different address.
- X */
- Xint fwd_packet(type_id, pkt, len, fwdto, replyto, i, cb)
- Xint type_id;
- Xvoidp pkt;
- Xint len;
- Xstruct sockaddr_in *fwdto, *replyto;
- Xvoidp i;
- Xfwd_fun cb;
- X{
- X rpc_forward *p;
- X u_int *pkt_int;
- X int error;
- X
- X if ((int)amd_state >= (int)Finishing)
- X return ENOENT;
- X
- X /*
- X * See if the type_id is fully specified.
- X * If so, then discard any old entries
- X * for this id.
- X * Otherwise make sure the type_id is
- X * fully qualified by allocating an id here.
- X */
- X#ifdef DEBUG
- X switch (type_id & RPC_XID_MASK) {
- X case RPC_XID_PORTMAP: dlog("Sending PORTMAP request"); break;
- X case RPC_XID_MOUNTD: dlog("Sending MOUNTD request %#x", type_id); break;
- X case RPC_XID_NFSPING: dlog("Sending NFS ping"); break;
- X default: dlog("UNKNOWN RPC XID"); break;
- X }
- X#endif
- X
- X if (type_id & ~RPC_XID_MASK) {
- X#ifdef DEBUG
- X /*dlog("Fully qualified rpc type provided");*/
- X#endif
- X p = fwd_locate(type_id);
- X if (p) {
- X#ifdef DEBUG
- X dlog("Discarding earlier rpc fwd handle");
- X#endif
- X fwd_free(p);
- X }
- X } else {
- X#ifdef DEBUG
- X dlog("Allocating a new xid...");
- X#endif
- X type_id = MK_RPC_XID(type_id, XID_ALLOC());
- X }
- X
- X p = fwd_alloc();
- X if (!p)
- X return ENOBUFS;
- X
- X error = 0;
- X
- X pkt_int = (u_int *) pkt;
- X
- X /*
- X * Get the original packet id
- X */
- X p->rf_oldid = *pkt_int;
- X
- X /*
- X * Replace with newly allocated id
- X */
- X p->rf_xid = *pkt_int = type_id;
- X
- X /*
- X * The sendto may fail if, for example, the route
- X * to a remote host is lost because an intermediate
- X * gateway has gone down. Important to fill in the
- X * rest of "p" otherwise nasty things happen later...
- X */
- X#ifdef DEBUG
- X dlog("Sending packet id %#x to %#08x.%04x", p->rf_xid, ntohl(fwdto->sin_addr.s_addr), ntohs(fwdto->sin_port));
- X#endif
- X if (sendto(fwd_sock, (char *) pkt, len, 0,
- X (struct sockaddr *) fwdto, sizeof(*fwdto)) < 0)
- X error = errno;
- X
- X /*
- X * Save callback function and return address
- X */
- X p->rf_fwd = cb;
- X if (replyto)
- X p->rf_sin = *replyto;
- X else
- X bzero((voidp) &p->rf_sin, sizeof(p->rf_sin));
- X p->rf_ptr = i;
- X
- X return error;
- X}
- X
- X/*
- X * Called when some data arrives on the forwarding socket
- X */
- Xvoid fwd_reply()
- X{
- X int len;
- X#ifdef DYNAMIC_BUFFERS
- X voidp pkt;
- X#else
- X u_int pkt[MAX_PACKET_SIZE/sizeof(u_int)+1];
- X#endif
- X u_int *pkt_int;
- X int rc;
- X rpc_forward *p;
- X struct sockaddr_in src_addr;
- X int src_addr_len;
- X
- X /*
- X * Determine the length of the packet
- X */
- X#ifdef DYNAMIC_BUFFERS
- X if (ioctl(fwd_sock, FIONREAD, &len) < 0) {
- X plog(XLOG_ERROR, "Error reading packet size: %m");
- X return;
- X }
- X
- X /*
- X * Allocate a buffer
- X */
- X pkt = (voidp) malloc((unsigned) len);
- X if (!pkt) {
- X plog(XLOG_ERROR, "Out of buffers in fwd_reply");
- X return;
- X }
- X#else
- X len = MAX_PACKET_SIZE;
- X#endif
- X
- X /*
- X * Read the packet and check for validity
- X */
- Xagain:
- X src_addr_len = sizeof(src_addr);
- X rc = recvfrom(fwd_sock, (char *) pkt, len, 0,
- X (struct sockaddr *) &src_addr, &src_addr_len);
- X if (rc < 0 || src_addr_len != sizeof(src_addr) ||
- X src_addr.sin_family != AF_INET) {
- X if (rc < 0 && errno == EINTR)
- X goto again;
- X plog(XLOG_ERROR, "Error reading RPC reply: %m");
- X goto out;
- X }
- X
- X#ifdef DYNAMIC_BUFFERS
- X if (rc != len) {
- X plog(XLOG_ERROR, "Short read in fwd_reply");
- X goto out;
- X }
- X#endif
- X
- X /*
- X * Do no more work if finishing soon
- X */
- X if ((int)amd_state >= (int)Finishing)
- X goto out;
- X
- X /*
- X * Find packet reference
- X */
- X pkt_int = (u_int *) pkt;
- X
- X#ifdef DEBUG
- X switch (*pkt_int & RPC_XID_MASK) {
- X case RPC_XID_PORTMAP: dlog("Receiving PORTMAP reply"); break;
- X case RPC_XID_MOUNTD: dlog("Receiving MOUNTD reply %#x", *pkt_int); break;
- X case RPC_XID_NFSPING: dlog("Receiving NFS ping %#x", *pkt_int); break;
- X default: dlog("UNKNOWN RPC XID"); break;
- X }
- X#endif
- X
- X p = fwd_locate(*pkt_int);
- X if (!p) {
- X#ifdef DEBUG
- X dlog("Can't forward reply id %#x", *pkt_int);
- X#endif
- X goto out;
- X }
- X
- X if (p->rf_fwd) {
- X /*
- X * Put the original message id back
- X * into the packet.
- X */
- X *pkt_int = p->rf_oldid;
- X
- X /*
- X * Call forwarding function
- X */
- X (*p->rf_fwd)(pkt, rc, &src_addr, &p->rf_sin, p->rf_ptr, TRUE);
- X }
- X
- X /*
- X * Free forwarding info
- X */
- X fwd_free(p);
- X
- Xout:;
- X#ifdef DYNAMIC_BUFFERS
- X /*
- X * Free the packet
- X */
- X free(pkt);
- X#endif
- X}
- END_OF_FILE
- if test 8861 -ne `wc -c <'rpc_fwd.c'`; then
- echo shar: \"'rpc_fwd.c'\" unpacked with wrong size!
- fi
- # end of 'rpc_fwd.c'
- fi
- echo shar: End of archive 6 \(of 13\).
- cp /dev/null ark6isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 13 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- exit 0 # Just in case...
-